/** bcmi_frame Binary writer definition.
 *
 *  bcmi_frame Binary writer definition. 
 *  This is the major worker implement the StreamWriter and StreamSender.
 *
 *  @author : huicong
 *  @date : 2008-10-27
 *
 */

#ifndef _MPI_WRITER_H
#define _MPI_WRITER_H

#include "StreamSender.h"
#include "StreamWriter.h"
#include "LogRecorder.h"

namespace bcmi_frame
{

    /**
     *
     * //UNDO
     *
     */
    class MPIWriter : public StreamSender, public StreamWriter
    {
    public:

        /** Initialize Function
         *
         *  @param [IN] UINT _rid : the remote process id in mpi.
         *  @param [INOUT] LogRecorder *_log : log recorder.
         *
         */
        MPIWriter(IN UINT _rid, INOUT LogRecorder *_log);

        /** Initialize Function
         *
         *  @param [IN] UINT _rid : the remote process id in mpi.
         *  @param [_IN] ParallelFrame *_frame : the frame this writer be init
         *
         */
        MPIWriter(IN UINT _rid, _IN ParallelFrame *_frame);

        ~MPIWriter();

    public:

        /** @see StreamSender::putBufferPool */
        HRESULT putBufferPool();

        /** @see StreamWriter::write */
        HRESULT write(IN VOID* _buf, IN UINT _size, OUT UINT &_actualSize);

    public:

        /** return the remote process mpi id */
        UINT getRemotePid();

    private:

        VOID initialize();

        /** send data from nid pool to remote process */
        HRESULT send(IN INT nid);

        /** set nid pool head info : _sendFlag & _realSize */
        VOID setHeadInfo(IN INT nid);

    private:

        UINT _remotePid; //remote process mpi id

        LogRecorder *_myLog;

        BYTE _sendFlag; // test whether this pool is the last pool
        const static BYTE _SEND_OVER = 0;
        const static BYTE _SEND_CONTINUE = 1;
        UINT _realSize; // the last pool real size

        /** Buffer head define.
         *
         *  |-------------|
         *  |0|1234|567...|
         *  |s|rs  |data..|
         *  |-------------|
         *
         *  s : _sendFlag
         *  rs : _realSize
         * 
         */
        const static UINT _BUFFER_HEAD_SIZE = 5;

    };

};

#endif //#ifndef _MPI_WRITER_H
